package com.sz.common.pay.pingan.core.server;

import com.sz.common.pay.common.PayLogger;
import com.sz.common.pay.pingan.constant.Constant;
import com.sz.common.pay.pingan.constant.ResponseCode;
import com.sz.common.pay.pingan.exception.OperationFailedException;
import com.sz.common.pay.pingan.exception.PayCommonException;
import com.sz.common.pay.pingan.util.CharSetUtil;
import com.sz.common.pay.pingan.util.PayExceptionUtil;

import java.util.HashMap;

/**
 * Function: 解析银行发送报文 <br>
 *
 * @author: siqishangshu <br>
 * @date: 2017-12-19 15:53:00
 * 通信报文头(222) + 变长报文体 + 报文附件（非必须）
 * “通信报文头”为固定长度222 字节；
 * “变长报文体”为报文的正文，其长度定义在报文头中 “接收报文长度” 第六个域；
 * “报文附件”（非必须部分）又分为：附件报文头277 + 附件内容 + 附件签名，其中附件签名，客户无须实现，统一送空。
 * 银行提供的客户端报文签名，是对“通信报文头(222) + 变长报文体 + 报文附件（非必须）”三部分的整体部分签名生成报文签名长度和签名数据，
 * 其格式为：6位签名内容长度+签名内容，客户无需关心，由b2bic前置机自动组装在报文后面。
 * 长度和属性列：Char代表字符串类型，Num代表数字类型。长度是指转换为byte后的固定长度，若输入内容不足对应长度，请按照“字符右补空格，数字左补0”规则补足。
 */

public class HttpRequestConverter {

    public static final int NET_HEAD_BYTE = 222;
    public static final int TRAN_FUNC_BYTE = 226;
    public static final int REP_MSG_BYTE_INDEX = 93;
    public static final int RSP_MSG_BYTE = 193;
    public static final int HEAD_MSG_BYTE = 344;
    public static final int RSP_CODE_BYTE_INDEX = 87;
    private static PayLogger payLogger = PayLogger.getLogger(HttpResponseConverter.class);

    /**
     * 解析接收银行的报文，入参String类型
     *
     * @param sequence
     * @param tranMessage
     * @return
     * @throws OperationFailedException 结果不是000000
     * @throws PayCommonException       其它异常，一般不应该出现
     */
    public HashMap parsingTranMessage(String sequence, String tranMessage) throws PayCommonException {
        HashMap retKeyDict = new HashMap();
        try {
            int i;
            byte[] bNetHead = new byte[NET_HEAD_BYTE];
            byte[] bTranFunc = new byte[TRAN_FUNC_BYTE];
            byte[] bRspCode = new byte[REP_MSG_BYTE_INDEX];
            byte[] bRspMsg = new byte[RSP_MSG_BYTE];
            byte[] bHeadMsg = new byte[HEAD_MSG_BYTE];

        /*获取返回码*/
            byte[] byteRetMessage = CharSetUtil.getBytesFromStringToGBK(tranMessage);
            for (i = 0; i < REP_MSG_BYTE_INDEX; i++) {
                bRspCode[i] = byteRetMessage[i];
            }
            String sRspCode = CharSetUtil.getStringFromBytesToGBK(bRspCode);
            sRspCode = sRspCode.substring(RSP_CODE_BYTE_INDEX);
            retKeyDict.put(Constant.RSP_CODE, sRspCode);

        /*获取返回信息*/
            byteRetMessage = CharSetUtil.getBytesFromStringToGBK(tranMessage);
            for (i = 0; i < RSP_MSG_BYTE; i++) {
                bRspMsg[i] = byteRetMessage[i];
            }
            String sRspMsg = CharSetUtil.getStringFromBytesToGBK(bRspMsg);
            sRspMsg = sRspMsg.substring(REP_MSG_BYTE_INDEX);
            retKeyDict.put(Constant.RSP_MSG_BAK, sRspMsg);
            sRspMsg = sRspMsg.trim();
            retKeyDict.put(Constant.RSP_MSG, sRspMsg);


            byteRetMessage = CharSetUtil.getBytesFromStringToGBK(tranMessage);
            for (i = 0; i < TRAN_FUNC_BYTE; i++) {
                bTranFunc[i] = byteRetMessage[i];
            }
            String sTranFunc = CharSetUtil.getStringFromBytesToGBK(bTranFunc);

            for (i = 0; i < NET_HEAD_BYTE; i++) {
                bNetHead[i] = byteRetMessage[i];
            }
            String sNetHead = CharSetUtil.getStringFromBytesToGBK(bNetHead);

            int iTranLength = sNetHead.length();
            sTranFunc = sTranFunc.substring(iTranLength);
            retKeyDict.put(Constant.TRAN_FUNC, sTranFunc);


        /*获取返回报文体*/
            byteRetMessage = CharSetUtil.getBytesFromStringToGBK(tranMessage);
            String sBodyMsg = CharSetUtil.getStringFromBytesToGBK(byteRetMessage);
            for (i = 0; i < HEAD_MSG_BYTE; i++) {
                bHeadMsg[i] = byteRetMessage[i];
            }
            String sHeadMsg = CharSetUtil.getStringFromBytesToGBK(bHeadMsg);
            int iLength = sHeadMsg.length();
            sBodyMsg = sBodyMsg.substring(iLength);
            retKeyDict.put(Constant.BOBY_MSG, sBodyMsg);

        /*解析报文体*/
            spiltMessage(retKeyDict);

        } catch (Exception e) {
            payLogger.error(sequence, "解析报文出错 :" + e.getMessage());
            PayExceptionUtil.throwPayCommonException("解析报文出错 :" + e.getMessage(), ResponseCode.ERR933);
        }
        return retKeyDict;
    }

    private void spiltMessage(HashMap retKeyDict) throws PayCommonException {
        int tranFunc = Integer.parseInt((String) retKeyDict.get(Constant.TRAN_FUNC));
        switch (tranFunc) {
            case 6000:
                //会员子账户开立 【6000】
//                spiltMessage_6000(retKeyDict);
                break;
            case 6005:
                //会员提现【6005】 （验证）
//                spiltMessage_HandFee(retKeyDict);
                break;
            //TODO NEW
            case 1303:
                //会员签解约维护【1303】
                spiltMessage_1303(retKeyDict);
                break;
            case 1310:
                //入金（银行发起）【1310】
                spiltMessage_1310(retKeyDict);
                break;
            case 1312:
                //出金（银行发起）【1312】
                spiltMessage_1312(retKeyDict);
                break;
            case 1326:
                //银行复核通知【1326】
                spiltMessage_1326(retKeyDict);
                break;
            default:
                PayExceptionUtil.throwPayCommonException("不支持的交易类型", ResponseCode.ERR935);
        }
    }

    private void spiltMessage_1326(HashMap retKeyDict) {

        if (retKeyDict.containsKey(Constant.BOBY_MSG)) {
            String bodyMessage = (String) retKeyDict.get(Constant.BOBY_MSG);
            String[] arryMessage = (bodyMessage + " ").split(Constant.MESSAGE_SPILT);

            retKeyDict.put("SupAcctId", arryMessage[0]);
            retKeyDict.put("FuncFlag", arryMessage[1]);
            retKeyDict.put("CheckResult", arryMessage[2]);
            retKeyDict.put("CustAcctId", arryMessage[3]);
            retKeyDict.put("ThirdCustId", arryMessage[4]);
            retKeyDict.put("TranAmount", arryMessage[5]);
            retKeyDict.put("HandFee", arryMessage[6]);
            retKeyDict.put("CcyCode", arryMessage[7]);
            retKeyDict.put("ThirdHtId", arryMessage[8]);
            retKeyDict.put("PaySerialNo", arryMessage[9]);
            retKeyDict.put("Note", arryMessage[10]);
            retKeyDict.put("Reserve", arryMessage[11]);
        }
    }

    private void spiltMessage_1312(HashMap retKeyDict) {

        if (retKeyDict.containsKey(Constant.BOBY_MSG)) {
            String bodyMessage = (String) retKeyDict.get(Constant.BOBY_MSG);
            String[] arryMessage = (bodyMessage + " ") .split(Constant.MESSAGE_SPILT);

            retKeyDict.put("TranWebName", arryMessage[0]);
            retKeyDict.put("ThirdCustId", arryMessage[1]);
            retKeyDict.put("CustAcctId", arryMessage[2]);
            retKeyDict.put("CustName", arryMessage[3]);
            retKeyDict.put("SupAcctId", arryMessage[4]);
            retKeyDict.put("OutAcctId", arryMessage[5]);
            retKeyDict.put("OutAcctIdName", arryMessage[6]);
            retKeyDict.put("CcyCode", arryMessage[7]);
            retKeyDict.put("TranAmount", arryMessage[8]);
            retKeyDict.put("HandFee", arryMessage[9]);
            retKeyDict.put("FeeOutCustId", arryMessage[10]);
            retKeyDict.put("Reserve", arryMessage[11]);
        }
    }

    private void spiltMessage_1310(HashMap retKeyDict) {
        if (retKeyDict.containsKey(Constant.BOBY_MSG)) {
            String bodyMessage = (String) retKeyDict.get(Constant.BOBY_MSG);
            String[] arryMessage = (bodyMessage + " ").split(Constant.MESSAGE_SPILT);

            retKeyDict.put("SupAcctId", arryMessage[0]);
            retKeyDict.put("CustAcctId", arryMessage[1]);
            retKeyDict.put("TranAmount", arryMessage[2]);
            retKeyDict.put("InAcctId", arryMessage[3]);
            retKeyDict.put("InAcctIdName", arryMessage[4]);
            retKeyDict.put("CcyCode", arryMessage[5]);
            retKeyDict.put("AcctDate", arryMessage[6]);
            retKeyDict.put("Reserve", arryMessage[7]);
        }
    }

    private void spiltMessage_1303(HashMap retKeyDict) {
        if (retKeyDict.containsKey(Constant.BOBY_MSG)) {
            String bodyMessage = (String) retKeyDict.get(Constant.BOBY_MSG);
            String[] arryMessage = (bodyMessage + " ").split(Constant.MESSAGE_SPILT);

            retKeyDict.put("FuncFlag", arryMessage[0]);
            retKeyDict.put("SupAcctId", arryMessage[1]);
            retKeyDict.put("CustAcctId", arryMessage[2]);
            retKeyDict.put("CustName", arryMessage[3]);
            retKeyDict.put("ThirdCustId", arryMessage[4]);
            retKeyDict.put("IdType", arryMessage[5]);
            retKeyDict.put("IdCode", arryMessage[6]);
            retKeyDict.put("RelatedAcctId", arryMessage[7]);
            retKeyDict.put("AcctFlag", arryMessage[8]);
            retKeyDict.put("TranType", arryMessage[9]);
            retKeyDict.put("AcctName", arryMessage[10]);
            retKeyDict.put("BankCode", arryMessage[11]);
            retKeyDict.put("BankName", arryMessage[12]);
            retKeyDict.put("OldRelatedAcctId", arryMessage[13]);
            retKeyDict.put("Reserve", arryMessage[14]);
        }
    }

    public String getTranFunCode(String tranMessage) throws PayCommonException {
        if ((tranMessage.length() < TRAN_FUNC_BYTE)) {
            PayExceptionUtil.throwPayCommonException("取交易码出错", ResponseCode.ERR952);
        }
        byte[] bTranFunc = new byte[TRAN_FUNC_BYTE];
        byte[] bNetHead = new byte[NET_HEAD_BYTE];
        byte[] byteRetMessage = CharSetUtil.getBytesFromStringToGBK(tranMessage);
        for (int i = 0; i < TRAN_FUNC_BYTE; i++) {
            bTranFunc[i] = byteRetMessage[i];
        }
        String sTranFunc = CharSetUtil.getStringFromBytesToGBK(bTranFunc);

        for (int i = 0; i < NET_HEAD_BYTE; i++) {
            bNetHead[i] = byteRetMessage[i];
        }
        String sNetHead = CharSetUtil.getStringFromBytesToGBK(bNetHead);
        return sTranFunc.substring(sNetHead.length());
    }


}
